﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using Pibby.Core.Logging;

namespace Pibby
{
	public static class ExceptionManager
	{
		enum ShowCallStackOption
		{
			ShowCallStack,
			HideCallStack
		}

		enum ShowInnerExceptionOption
		{
			ShowInnerExceptions,
			HideInnerExceptions
		}

		public static void LogException(Exception ex)
		{
			string message = BuildExceptionMessage(ex, ShowCallStackOption.ShowCallStack,
									ShowInnerExceptionOption.ShowInnerExceptions);

			Log.Error(message);
		}

		public static void LogException(OutOfMemoryException outOfMemory)
		{
			Log.Error(outOfMemory.Message);
		}

		public static void ShowException(Exception generalException)
		{
			string message = BuildExceptionMessage(generalException, ShowCallStackOption.ShowCallStack,
									ShowInnerExceptionOption.ShowInnerExceptions);

			Log.Error(message);

			string title = string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0} - {1}", Application.ProductName, generalException.GetType().ToString());

			MessageBox.Show(message, title, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
		}


		public static void ShowUnhandledException(Exception ex)
		{
			string message = BuildExceptionMessage(ex, ShowCallStackOption.ShowCallStack,
									ShowInnerExceptionOption.ShowInnerExceptions);

			Log.Error(message);

			string title = string.Format(System.Globalization.CultureInfo.CurrentCulture, "Unhandled exception in {0} - {1}", Application.ProductName, ex.GetType().ToString());

			using (UI.ExceptionMessageBox box = new Pibby.UI.ExceptionMessageBox(ex))
			{
				box.Text = title;
				box.ShowDialog();
			}
		}

		private static string BuildExceptionMessage(Exception ex, ShowCallStackOption includeCallStack, ShowInnerExceptionOption showInnerExceptions)
		{
			StringBuilder builder = new StringBuilder();

			builder.Append(ex.GetType().ToString());
			builder.AppendLine();
			builder.Append(ex.Message);
			builder.AppendLine();

			if (showInnerExceptions == ShowInnerExceptionOption.ShowInnerExceptions)
			{
				Exception inner = ex.InnerException;

				while (inner != null)
				{
					builder.Append(inner.GetType().ToString());
					builder.AppendLine();
					builder.Append(inner.Message);
					builder.AppendLine();

					inner = inner.InnerException;
				}
			}

			if (includeCallStack == ShowCallStackOption.ShowCallStack)
				builder.AppendFormat("*** Call Stack: {0} ***", ex.StackTrace);

			return builder.ToString();
		}

	}
}
